package com.macro.mall.demo.design.pattern.chain;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
public class Responsability implements IResponsability {

    @Autowired
    private List<IResponsability> responsabilityList;

    protected Map<String, IResponsability> responsabilityMap = Maps.newHashMap();

    @PostConstruct
    public void init() {
        responsabilityList.forEach(responsability -> {
                    if (!responsabilityMap.containsKey(responsability.getResponsabilityId())) {
                        responsabilityMap.put(responsability.getResponsabilityId(), responsability);
                    }
        });
    }

    @Override
    public String getResponsabilityId() {
        return "default";
    }

    @Override
    public void process(IChain chain, IResponsability responsability) {
        assert chain != null;
        buildChainIfNull(chain);
    }

    private void buildChainIfNull(IChain chain) {
        if(CollectionUtil.isNotEmpty(chain.getResponsabilityList())){
            return;
        }
        chain.setResponsabilityList(this.buildResponsabilityList(chain.getChainStr()));
    }

    private List<IResponsability> buildResponsabilityList(String chainStr) {
        List<IResponsability> responsabilityList = new ArrayList<>();
        if(StringUtils.isBlank(chainStr)){
            return responsabilityList;
        }
        String[] chainArr = StringUtils.split(chainStr,">");
        for(String chain : chainArr){
            chain = chain.trim();
            if(responsabilityMap.containsKey(chain)){
                IResponsability responsability =responsabilityMap.get(chain);
                if (responsability == null){
                    //TODO log
                    continue;
                }
                responsabilityList.add(responsability);
            }
        }
        return responsabilityList;
    }
}
